# Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
# This source file is part of the Cangjie project, licensed under Apache-2.0
# with Runtime Library Exception.
#
# See https://cangjie-lang.cn/pages/LICENSE for license information.


from os import path
import random

integer_types = ['Int8', 'Int16', 'Int32', 'Int64', 'UInt8', 'UInt16', 'UInt32', 'UInt64']
number_types = integer_types + ['Float16', 'Float32', 'Float64']
other_types = ['String', 'Rune', 'Bool', 'Unit', 'Tuple', 'Array', 'Range', 'C', 'S']
types = number_types + other_types
default_value_map = {'Bool' : 'true', 'Unit' : '()', 'Array' : '[1]', 'Rune' : "'1'", 'String' : '"1"',
                     'Tuple' : '(1, 1)', 'Range' : '1..2', 'C' : 'C(1)', 'S' : 'S(1)'}

def default_value(ty : str) -> str:
  if ty in integer_types: return '1' + ty[0].lower() + ty[ty.index('t')+1:]
  if 'Float' in ty: return '1.0f' + ty[5:]
  return default_value_map[ty]

dir = path.dirname(path.realpath(__file__))
path = dir + '/test_' + path.basename(dir) + '_{}.cj'
template = '''
/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
 * This source file is part of the Cangjie project, licensed under Apache-2.0
 * with Runtime Library Exception.
 *
 * See https://cangjie-lang.cn/pages/LICENSE for license information.
 */

/*
  @Assertion:   10.2.2.3(17)  4. The function call operator ( ()) overloaded functions have no requirements on input
                parameters and return value types. 
  @Description: Checks that overloading () works for various input parameters and return value types.
  @Mode: run
  @Negative: no
  @Structure: single
  @CompileWarning: ignore
  @Comment: Auto-generated by gen.py
*/

type Tuple = (Int64, Int64)
type Array = Array<Int64>
type Range = Range<Int64>

struct S {
    let x : Int64

    S(y : Int64) { x = y }
}

class C {
    let x : Int64

    C(y : Int64) { x = y }

%s
}

main() {
%s
}
'''
counter = 1

def write_counted(contents : str):
  global counter
  with open(path.format(str(counter).zfill(2)), 'w') as file:
    file.write(contents)
    counter += 1

random.seed(123)
limit = 20
def sample(dim : int):
  indices = random.sample(range(len(types)**dim), limit if limit < len(types)**dim else len(types)**dim)
  return [[types[e // (len(types)**i) % len(types)] for i in range(dim)] for e in indices]

signatures = [((t), random.choice(types)) for i in range(7) for t in sample(i)]
test = template % ('\n\n'.join(['    operator func ()(%s) : %s { %s }' %
                                (', '.join(['x%s: %s' % (j, at[j]) for j in range(len(at))]), rt, default_value(rt))
                                for at, rt in signatures]),
'\n'.join(['    let c%i : %s = C(1)(%s)' % (i, signatures[i][1], ', '.join([default_value(t) for t in signatures[i][0]]))
            for i in range(len(signatures))]))
write_counted(test)
